package com.hnfnu.contracts;

import org.fisco.bcos.sdk.v3.client.Client;
import org.fisco.bcos.sdk.v3.codec.datatypes.*;
import org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.v3.codec.datatypes.generated.tuples.generated.Tuple5;
import org.fisco.bcos.sdk.v3.codec.datatypes.generated.tuples.generated.Tuple6;
import org.fisco.bcos.sdk.v3.contract.Contract;
import org.fisco.bcos.sdk.v3.crypto.CryptoSuite;
import org.fisco.bcos.sdk.v3.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.v3.model.CryptoType;
import org.fisco.bcos.sdk.v3.model.TransactionReceipt;
import org.fisco.bcos.sdk.v3.model.callback.CallCallback;
import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@SuppressWarnings("unchecked")
public class DonationRecord extends Contract {
    public static final String[] BINARY_ARRAY = {"608060405234801561001057600080fd5b50610e3d806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806325d07c0f146100515780632d015f811461006d578063344610671461009d578063c2a4250b146100d2575b600080fd5b61006b60048036038101906100669190610907565b6100f0565b005b610087600480360381019061008291906109d6565b6101fb565b6040516100949190610bf3565b60405180910390f35b6100b760048036038101906100b291906109d6565b6104c4565b6040516100c996959493929190610c6e565b60405180910390f35b6100da610698565b6040516100e79190610ce4565b60405180910390f35b6001600081548092919061010390610d2e565b91905055506040518060c001604052806001548152602001868152602001858152602001848152602001838152602001828152506000806001548152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301908051906020019061018592919061069e565b5060808201518160040190805190602001906101a292919061069e565b5060a08201518160050190805190602001906101bf92919061069e565b5090505083856001547facae88f8c5ced2bba1920b1be99fa426c3fff4cd1d557ce6665f281b096c3e2260405160405180910390a45050505050565b6060600060015467ffffffffffffffff81111561021b5761021a6107dc565b5b60405190808252806020026020018201604052801561025457816020015b610241610724565b8152602001906001900390816102395790505b509050600080600190505b60015481116104b657846000808381526020019081526020016000206001015414156104a3576000808281526020019081526020016000206040518060c00160405290816000820154815260200160018201548152602001600282015481526020016003820180546102d090610da6565b80601f01602080910402602001604051908101604052809291908181526020018280546102fc90610da6565b80156103495780601f1061031e57610100808354040283529160200191610349565b820191906000526020600020905b81548152906001019060200180831161032c57829003601f168201915b5050505050815260200160048201805461036290610da6565b80601f016020809104026020016040519081016040528092919081815260200182805461038e90610da6565b80156103db5780601f106103b0576101008083540402835291602001916103db565b820191906000526020600020905b8154815290600101906020018083116103be57829003601f168201915b505050505081526020016005820180546103f490610da6565b80601f016020809104026020016040519081016040528092919081815260200182805461042090610da6565b801561046d5780601f106104425761010080835404028352916020019161046d565b820191906000526020600020905b81548152906001019060200180831161045057829003601f168201915b50505050508152505083838151811061048957610488610dd8565b5b6020026020010181905250818061049f90610d2e565b9250505b80806104ae90610d2e565b91505061025f565b508082528192505050919050565b60006020528060005260406000206000915090508060000154908060010154908060020154908060030180546104f990610da6565b80601f016020809104026020016040519081016040528092919081815260200182805461052590610da6565b80156105725780601f1061054757610100808354040283529160200191610572565b820191906000526020600020905b81548152906001019060200180831161055557829003601f168201915b50505050509080600401805461058790610da6565b80601f01602080910402602001604051908101604052809291908181526020018280546105b390610da6565b80156106005780601f106105d557610100808354040283529160200191610600565b820191906000526020600020905b8154815290600101906020018083116105e357829003601f168201915b50505050509080600501805461061590610da6565b80601f016020809104026020016040519081016040528092919081815260200182805461064190610da6565b801561068e5780601f106106635761010080835404028352916020019161068e565b820191906000526020600020905b81548152906001019060200180831161067157829003601f168201915b5050505050905086565b60015481565b8280546106aa90610da6565b90600052602060002090601f0160209004810192826106cc5760008555610713565b82601f106106e557805160ff1916838001178555610713565b82800160010185558215610713579182015b828111156107125782518255916020019190600101906106f7565b5b509050610720919061075a565b5090565b6040518060c001604052806000815260200160008152602001600081526020016060815260200160608152602001606081525090565b5b8082111561077357600081600090555060010161075b565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61079e8161078b565b81146107a957600080fd5b50565b6000813590506107bb81610795565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610814826107cb565b810181811067ffffffffffffffff82111715610833576108326107dc565b5b80604052505050565b6000610846610777565b9050610852828261080b565b919050565b600067ffffffffffffffff821115610872576108716107dc565b5b61087b826107cb565b9050602081019050919050565b82818337600083830152505050565b60006108aa6108a584610857565b61083c565b9050828152602081018484840111156108c6576108c56107c6565b5b6108d1848285610888565b509392505050565b600082601f8301126108ee576108ed6107c1565b5b81356108fe848260208601610897565b91505092915050565b600080600080600060a0868803121561092357610922610781565b5b6000610931888289016107ac565b9550506020610942888289016107ac565b945050604086013567ffffffffffffffff81111561096357610962610786565b5b61096f888289016108d9565b935050606086013567ffffffffffffffff8111156109905761098f610786565b5b61099c888289016108d9565b925050608086013567ffffffffffffffff8111156109bd576109bc610786565b5b6109c9888289016108d9565b9150509295509295909350565b6000602082840312156109ec576109eb610781565b5b60006109fa848285016107ac565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b610a388161078b565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a78578082015181840152602081019050610a5d565b83811115610a87576000848401525b50505050565b6000610a9882610a3e565b610aa28185610a49565b9350610ab2818560208601610a5a565b610abb816107cb565b840191505092915050565b600060c083016000830151610ade6000860182610a2f565b506020830151610af16020860182610a2f565b506040830151610b046040860182610a2f565b5060608301518482036060860152610b1c8282610a8d565b91505060808301518482036080860152610b368282610a8d565b91505060a083015184820360a0860152610b508282610a8d565b9150508091505092915050565b6000610b698383610ac6565b905092915050565b6000602082019050919050565b6000610b8982610a03565b610b938185610a0e565b935083602082028501610ba585610a1f565b8060005b85811015610be15784840389528151610bc28582610b5d565b9450610bcd83610b71565b925060208a01995050600181019050610ba9565b50829750879550505050505092915050565b60006020820190508181036000830152610c0d8184610b7e565b905092915050565b610c1e8161078b565b82525050565b600082825260208201905092915050565b6000610c4082610a3e565b610c4a8185610c24565b9350610c5a818560208601610a5a565b610c63816107cb565b840191505092915050565b600060c082019050610c836000830189610c15565b610c906020830188610c15565b610c9d6040830187610c15565b8181036060830152610caf8186610c35565b90508181036080830152610cc38185610c35565b905081810360a0830152610cd78184610c35565b9050979650505050505050565b6000602082019050610cf96000830184610c15565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610d398261078b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610d6c57610d6b610cff565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610dbe57607f821691505b60208210811415610dd257610dd1610d77565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220712b95274fd656be7a979f844b2b222e32bb7037d0a0c9b1abf377a4c04c773e64736f6c634300080b0033"};

    public static final String BINARY = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", BINARY_ARRAY);

    public static final String[] SM_BINARY_ARRAY = {};

    public static final String SM_BINARY = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);

    public static final String[] ABI_ARRAY = {"[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"userId\",\"type\":\"uint256\"}],\"name\":\"RecordAdded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"userId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"remark\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"money\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recordTime\",\"type\":\"string\"}],\"name\":\"addRecord\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"}],\"name\":\"getRecordsByProjectId\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"userId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"remark\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"money\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recordTime\",\"type\":\"string\"}],\"internalType\":\"struct DonationRecord.Record[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlockId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"records\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"userId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"remark\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"money\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recordTime\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"};

    public static final String ABI = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", ABI_ARRAY);

    public static final String FUNC_ADDRECORD = "addRecord";

    public static final String FUNC_GETRECORDSBYPROJECTID = "getRecordsByProjectId";

    public static final String FUNC_LASTBLOCKID = "lastBlockId";

    public static final String FUNC_RECORDS = "records";

    public static final Event RECORDADDED_EVENT = new Event("RecordAdded", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>(true) {}, new TypeReference<Uint256>(true) {}, new TypeReference<Uint256>(true) {}));
    ;

    protected DonationRecord(String contractAddress, Client client, CryptoKeyPair credential) {
        super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
    }

    public static String getBinary(CryptoSuite cryptoSuite) {
        return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
    }

    public static String getABI() {
        return ABI;
    }

    public List<RecordAddedEventResponse> getRecordAddedEvents(
            TransactionReceipt transactionReceipt) {
        List<Contract.EventValuesWithLog> valueList = extractEventParametersWithLog(RECORDADDED_EVENT, transactionReceipt);
        ArrayList<RecordAddedEventResponse> responses = new ArrayList<RecordAddedEventResponse>(valueList.size());
        for (Contract.EventValuesWithLog eventValues : valueList) {
            RecordAddedEventResponse typedResponse = new RecordAddedEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse.blockId = (BigInteger) eventValues.getIndexedValues().get(0).getValue();
            typedResponse.projectId = (BigInteger) eventValues.getIndexedValues().get(1).getValue();
            typedResponse.userId = (BigInteger) eventValues.getIndexedValues().get(2).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public TransactionReceipt addRecord(BigInteger projectId, BigInteger userId, String remark,
            String money, String recordTime) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(userId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(remark), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(money), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime)), 
                Collections.<TypeReference<?>>emptyList(), 0);
        return executeTransaction(function);
    }

    public String getSignedTransactionForAddRecord(BigInteger projectId, BigInteger userId,
            String remark, String money, String recordTime) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(userId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(remark), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(money), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime)), 
                Collections.<TypeReference<?>>emptyList(), 0);
        return createSignedTransaction(function);
    }

    public String addRecord(BigInteger projectId, BigInteger userId, String remark, String money,
            String recordTime, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(userId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(remark), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(money), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime)), 
                Collections.<TypeReference<?>>emptyList(), 0);
        return asyncExecuteTransaction(function, callback);
    }

    public Tuple5<BigInteger, BigInteger, String, String, String> getAddRecordInput(
            TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_ADDRECORD, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = this.functionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple5<BigInteger, BigInteger, String, String, String>(

                (BigInteger) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue()
                );
    }

    public List<Record> getRecordsByProjectId(BigInteger projectId) throws
            ContractException {
        final Function function = new Function(FUNC_GETRECORDSBYPROJECTID, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<Record>>() {}));
        return executeCallWithSingleValueReturn(function, List.class);
    }

    public void getRecordsByProjectId(BigInteger projectId, CallCallback callback) throws
            ContractException {
        final Function function = new Function(FUNC_GETRECORDSBYPROJECTID, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<Record>>() {}));
        asyncExecuteCall(function, callback);
    }

    public BigInteger lastBlockId() throws ContractException {
        final Function function = new Function(FUNC_LASTBLOCKID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public void lastBlockId(CallCallback callback) throws ContractException {
        final Function function = new Function(FUNC_LASTBLOCKID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        asyncExecuteCall(function, callback);
    }

    public Tuple6<BigInteger, BigInteger, BigInteger, String, String, String> records(
            BigInteger param0) throws ContractException {
        final Function function = new Function(FUNC_RECORDS, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(param0)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = executeCallWithMultipleValueReturn(function);
        return new Tuple6<BigInteger, BigInteger, BigInteger, String, String, String>(
                (BigInteger) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue(), 
                (BigInteger) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue(), 
                (String) results.get(5).getValue());
    }

    public void records(BigInteger param0, CallCallback callback) throws ContractException {
        final Function function = new Function(FUNC_RECORDS, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(param0)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        asyncExecuteCall(function, callback);
    }

    public static DonationRecord load(String contractAddress, Client client,
            CryptoKeyPair credential) {
        return new DonationRecord(contractAddress, client, credential);
    }

    public static DonationRecord deploy(Client client, CryptoKeyPair credential) throws
            ContractException {
        return deploy(DonationRecord.class, client, credential, getBinary(client.getCryptoSuite()), getABI(), null, null);
    }

    public static class Record extends DynamicStruct {
        public BigInteger blockId;

        public BigInteger projectId;

        public BigInteger userId;

        public String remark;

        public String money;

        public String recordTime;

        public Record(Uint256 blockId, Uint256 projectId, Uint256 userId, Utf8String remark,
                Utf8String money, Utf8String recordTime) {
            super(blockId,projectId,userId,remark,money,recordTime);
            this.blockId = blockId.getValue();
            this.projectId = projectId.getValue();
            this.userId = userId.getValue();
            this.remark = remark.getValue();
            this.money = money.getValue();
            this.recordTime = recordTime.getValue();
        }

        public Record(BigInteger blockId, BigInteger projectId, BigInteger userId, String remark,
                String money, String recordTime) {
            super(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(blockId),new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId),new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(userId),new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(remark),new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(money),new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime));
            this.blockId = blockId;
            this.projectId = projectId;
            this.userId = userId;
            this.remark = remark;
            this.money = money;
            this.recordTime = recordTime;
        }
    }

    public static class RecordAddedEventResponse {
        public TransactionReceipt.Logs log;

        public BigInteger blockId;

        public BigInteger projectId;

        public BigInteger userId;
    }
}
